home *** CD-ROM | disk | FTP | other *** search
- /* Copyright (c) 1992 NeXT Computer, Inc. All rights reserved.
- *
- * File: architecture/m98k/basic_regs.h
- * Author: Doug Mitchell, NeXT Computer, Inc.
- *
- * Basic m98k registers.
- *
- * HISTORY
- * 05-Nov-92 Doug Mitchell at NeXT
- * Created.
- */
-
- #ifndef _ARCH_M98K_BASIC_REGS_H_
- #define _ARCH_M98K_BASIC_REGS_H_
-
- #import <architecture/m98k/reg_help.h>
- #import <architecture/nrw/macro_help.h>
-
- /*
- * Number of General Purpose registers.
- */
- #define M98K_NGP_REGS 32
-
- /*
- * Common half-word used in Machine State Register and in
- * various exception frames. Defined as a macro because the compiler
- * will align a struct to a word boundary when used inside another struct.
- */
- #define MSR_BITS \
- unsigned ee:BIT_WIDTH(15), /* external intr enable */ \
- pr:BIT_WIDTH(14), /* problem state */ \
- fp:BIT_WIDTH(13), /* floating point avail */ \
- me:BIT_WIDTH(12), /* machine check enable */ \
- fe0:BIT_WIDTH(11), /* fp exception mode 0 */ \
- se:BIT_WIDTH(10), /* single step enable */ \
- be:BIT_WIDTH(9), /* branch trace enable */ \
- fe1:BIT_WIDTH(8), /* fp exception mode 0 */ \
- rsvd1:BIT_WIDTH(7), /* reserved */ \
- ip:BIT_WIDTH(6), /* interrupt prefix */ \
- ir:BIT_WIDTH(5), /* instruction relocate */ \
- dr:BIT_WIDTH(4), /* data relocate */ \
- rsvd2:BITS_WIDTH(3,1), /* reserved */ \
- psfr:BIT_WIDTH(0) /* 64 bit mode */
-
- /*
- * Machine state register.
- * Read and written via get_msr() and set_msr() inlines, below.
- */
- typedef struct {
- unsigned rsvd3:BITS_WIDTH(31,16); // reserved
- MSR_BITS; // see above
- } msr_t;
-
- /*
- * Data Storage Interrupt Status Register (DSISR)
- */
- typedef struct {
- unsigned dse:BIT_WIDTH(31); // direct-store error
- unsigned tnf:BIT_WIDTH(30); // translation not found
- unsigned :BITS_WIDTH(29,28);
- unsigned pe:BIT_WIDTH(27); // protection error
- unsigned dsr:BIT_WIDTH(26); // lwarx/stwcx to direct-store
- unsigned rw:BIT_WIDTH(25); // 1 => store, 0 => load
- unsigned :BITS_WIDTH(24,23);
- unsigned dab:BIT_WIDTH(22); // data address bkpt (601)
- unsigned ssf:BIT_WIDTH(21); // seg table search failed
- unsigned :BITS_WIDTH(20,0);
- } dsisr_t;
-
- /*
- * Instruction Storage Interrupt Status Register (really SRR1)
- */
- typedef struct {
- unsigned :BIT_WIDTH(31);
- unsigned tnf:BIT_WIDTH(30); // translation not found
- unsigned :BIT_WIDTH(29);
- unsigned dse:BIT_WIDTH(28); // direct-store fetch error
- unsigned pe:BIT_WIDTH(27); // protection error
- unsigned :BITS_WIDTH(26,22);
- unsigned ssf:BIT_WIDTH(21); // seg table search failed
- unsigned :BITS_WIDTH(20,16);
- MSR_BITS;
- } isisr_t;
-
- /*
- * Alignment Interrupt Status Register (really DSISR)
- * NOTE: bit numbers in field *names* are in IBM'ese (0 is MSB).
- * FIXME: Yuck!!! Double Yuck!!!
- */
- typedef struct {
- unsigned :BITS_WIDTH(31,20);
- unsigned ds3031:BITS_WIDTH(19,18);// bits 30:31 if DS form
- unsigned :BIT_WIDTH(17);
- unsigned x2930:BITS_WIDTH(16,15); // bits 29:30 if X form
- unsigned x25:BIT_WIDTH(14); // bit 25 if X form or
- // bit 5 if D or DS form
- unsigned x2124:BITS_WIDTH(13,10); // bits 21:24 if X form or
- // bits 1:4 if D or DS form
- unsigned all615:BITS_WIDTH(9,0); // bits 6:15 of instr
- MSR_BITS;
- } aisr_t;
-
- /*
- * Program Interrupt Status Register (really SRR1)
- */
- typedef struct {
- unsigned :BITS_WIDTH(31,21);
- unsigned fpee:BIT_WIDTH(20); // floating pt enable exception
- unsigned ill:BIT_WIDTH(19); // illegal instruction
- unsigned priv:BIT_WIDTH(18); // privileged instruction
- unsigned trap:BIT_WIDTH(17); // trap program interrupt
- unsigned subseq:BIT_WIDTH(16); // 1 => SRR0 points to
- // subsequent instruction
- MSR_BITS;
- } pisr_t;
-
- /*
- * Condition register. May not be useful in C, let's see...
- */
- typedef struct {
- unsigned lt:BIT_WIDTH(31), // negative
- gt:BIT_WIDTH(30), // positive
- eq:BIT_WIDTH(29), // equal to zero
- so:BIT_WIDTH(28), // summary overflow
- fx:BIT_WIDTH(27), // floating point exception
- fex:BIT_WIDTH(26), // fp enabled exception
- vx:BIT_WIDTH(25), // fp invalid operation
- // exception
- ox:BIT_WIDTH(24), // fp overflow exception
- rsvd:BITS_WIDTH(23,0); // reserved
- } cr_t;
-
- /*
- * Program mode register.
- * Read and written via get_prog_mode() and set_prog_mode() inlines, below.
- *
- * NOT SUPPORTED ON M98601
- */
- typedef struct {
- unsigned rsvd1:BITS_WIDTH(31,12),
- fe0:BIT_WIDTH(11),
- rsvd2:BITS_WIDTH(10,9),
- fe1:BIT_WIDTH(8),
- rsvd3:BITS_WIDTH(7,1),
- sf:BIT_WIDTH(0); // 64 bit mode
- } prog_mode_t;
-
- /*
- * Abstract values representing fe0:fe1.
- * See get_fp_exc_mode(), below.
- */
- typedef enum {
- FEM_IGNORE_EXCEP, // ignore exceptions
- FEM_IMPR_NONREC, // imprecise nonrecoverable
- FEM_IMPR_RECOV, // imprecise recoverable
- FEM_PRECISE,
- } fp_exc_mode_t;
-
-
- /*
- * Special purpose registers.
- */
-
- /*
- * Processor version register (special purpose register pvr).
- */
- typedef struct {
- unsigned version:BITS_WIDTH(31,16),
- revision:BITS_WIDTH(15,0);
- } pvr_t;
-
- /*
- * Fixed point exception register (special purpose register xer)
- */
- typedef struct {
- unsigned so:BIT_WIDTH(31), // summary overflow
- ov:BIT_WIDTH(30), // overflow
- ca:BIT_WIDTH(29), // carry
- rsvd1:BITS_WIDTH(28,16),// reserved
- byte:BITS_WIDTH(15,8), // byte to be compared
- rsvd2:BIT_WIDTH(7), // reserved
- byte_count:BITS_WIDTH(6,0);
- } xer_t;
-
- /*
- * Inlines and macros to manipulate the above registers.
- */
-
- /*
- * Get/set machine state register.
- */
- static __inline__ msr_t
- get_msr()
- {
- msr_t __msr_tmp;
-
- __asm__ volatile ("mfmsr %0 /* mfmsr */" \
- : "=r" (__msr_tmp));
- return __msr_tmp;
- }
-
- static __inline__ void
- set_msr(msr_t msr)
- {
- __asm__ volatile ("mtmsr %0 /* mtmsr */ " \
- : : "r" (msr));
- }
-
- /*
- * Read/write program mode register.
- *
- * NOT SUPPORTED ON M98601
- */
- static __inline__ prog_mode_t
- get_prog_mode()
- {
- prog_mode_t __pm_tmp;
- __asm__ volatile ("mfpmr %0 /* mfpmr */" \
- : "=r" (__pm_tmp));
- return __pm_tmp;
- }
-
- static __inline__ void
- set_prog_mode(prog_mode_t prog_mode)
- {
- __asm__ volatile ("mtpmr %0; /* mtpmr */ " \
- : : "r" (prog_mode));
- }
-
-
- /*
- * Determine current fp_exc_mode_t given prog_mode.
- */
- static __inline__ fp_exc_mode_t
- get_fp_exc_mode(prog_mode_t prog_mode)
- {
- if(prog_mode.fe0) {
- return prog_mode.fe1 ? FEM_PRECISE : FEM_IMPR_RECOV;
- }
- else {
- return prog_mode.fe1 ? FEM_IMPR_NONREC : FEM_IGNORE_EXCEP;
- }
- }
-
- /*
- * Software definitions for special purpose registers.
- * The same register is used as per_cpu data pointer and
- * vector base register. This requires that the vector
- * table be the first item in the per_cpu table.
- */
- #define SR_EXCEPTION_TMP_LR sprg0
- #define SR_EXCEPTION_TMP_CR sprg1
- #define SR_EXCEPTION_TMP_AT sprg2
- #define SR_PER_CPU_DATA sprg3
- #define SR_VBR sprg3
-
- /*
- * Get/set special purpose registers.
- *
- * GET_SPR - get SPR by name.
- *
- * Example usage:
- *
- * {
- * xer_t some_xer;
- *
- * some_xer = GET_SPR(xer_t, xer);
- * ...
- * }
- *
- * This is a strange one. We're creating a list of C expressions within
- * a set of curlies; the last expression ("__spr_tmp;") is the return value
- * of the statement created by the curlies.
- *
- * WARNING: The m88k version of this did not compile with -O2. Let's hope
- * the 2.2.2 compiler fixes this.
- */
-
- #define GET_SPR(type, spr) \
- ({ \
- unsigned __spr_tmp; \
- __asm__ volatile ("mfspr %0, " STRINGIFY(spr) \
- : "=r" (__spr_tmp)); \
- *(type *)&__spr_tmp; \
- })
-
- /*
- * Example usage of SET_SPR:
- *
- * {
- * xer_t some_xer;
- *
- * ...set up some_xer...
- * SET_SPR(xer, some_xer);
- * }
- */
- #define SET_SPR(spr, val) \
- MACRO_BEGIN \
- __typeof__ (val) __spr_tmp = (val); \
- __asm__ volatile ("mtspr "STRINGIFY(spr) ", %0" \
- : : "r" (__spr_tmp)); \
- MACRO_END
-
- /*
- * Fully synchronize instruction stream.
- */
- static __inline__ void
- m98k_sync()
- {
- __asm__ volatile ("sync /* sync */" \
- : : );
- }
-
- #endif _ARCH_M98K_BASIC_REGS_H_
-
-